#include "AppendFile.h"

#include "wrap/error.h"
#include "wrap/stdios.h"


AppendFile::AppendFile(const std::string &filename):
    _buffer{},
    _filename{filename},
    _stream{Wrap::fopen_(filename.c_str(), "ae")},
    _writtenBytes{0} {
        ::setbuffer(_stream, _buffer.data(), _buffer.size());
}

AppendFile::~AppendFile() {
    Wrap::fclose_(_stream);
}

void AppendFile::append(const char *buffer, std::size_t length) {
    auto n1 = _write(buffer, length);
    auto remain = length - n1;
    while (remain > 0)
    {
        auto n2 = _write(buffer + n1, remain);
        if (n2 == 0) {
            const auto err = ::ferror(_stream);
            if (err != 0) {
                ::fprintf(
                    stderr, "AppendFile::%s() failed: %s\n", __func__, Wrap::strerror_r_(err));
            }
            break;
        }
        n1 += n2;
        remain = length - n2;
    }
    _writtenBytes += length;
}

void AppendFile::flush() {
    Wrap::fflush_(_stream);
}


std::size_t AppendFile::_write(const char * buffer, std::size_t length) {
    return ::fwrite(buffer, 1, length, _stream);
}
